#include<stdio.h>
#include<string.h>
#include<unistd.h>
#include<sys/wait.h>
#include<sys/types.h>
#include<stdlib.h>

#define SIZE 32 
#define NUM 1024
#define SEP " "

char cmd_line[NUM];//缓冲区：保存完整的命令行字符串

char* g_argv[SIZE];//保存打散之后的命令行字符串

// shell 运行原理： 通过让子进程执行命令，父进程等待&&解析命令
int main()
{
  while(1)
  {
    //1、打印出提示信息 [PD@localhost myshell]#                                                          
    printf("[PD@lcalhost myshell]# "); 
    sleep(1); 
    fflush(stdout);
    memset(cmd_line,'\0',sizeof cmd_line);
    //2、获取用户的键盘输入[输入的是各种指令和选项： “l -a -l
    
    if(fgets(cmd_line,sizeof cmd_line,stdin) == NULL)
    {
        continue;
    }
    cmd_line[strlen(cmd_line) - 1] = '\0';
    printf("echo:%s\n",cmd_line);
    //3、命令行字符串解析“"ls -a -l -i" -> "ls" "-a" "-l" "-i"
    g_argv[0] = strtok(cmd_line,SEP);
    int index = 1;
    if(strcmp(g_argv[0],"ls") == 0)
    {
      g_argv[index++] = "--color=auto";
    }
    while(g_argv[index++] = strtok(NULL,SEP));
  
    //for debug
    for(index = 0;g_argv[index];index++)
    {
      printf("g_argv[%d]: %s\n", index,g_argv[index]);
    }
    //4、内置命令
    if(strcmp(g_argv[0],"cd") == 0)
    {
      if(g_argv[1] != NULL) chdir(g_argv[1]);

      continue;
    }
    //5、
    pid_t id = fork();
    if(id == 0)
    {
      //子进程
      printf("下面是子进程的功能\n");
      execvp(g_argv[0],g_argv);
      exit(1);
    }
    int status = 0;
    pid_t ret = waitpid(id,&status,0);
    if(ret > 0)
      printf("exit code:%d\n",WEXITSTATUS(status));

  }
  
}
